package net.lcqf.tcp.server;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.SimpleChannelInboundHandler;
import net.lcqf.tcp.send.MessageFactory;
import net.lcqf.tcp.send.RequestType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;


/**
 * TcpServerHandler
 * +----------------------------------------------------------------------
 * | Talk To [ 聊来改善地区金融服务环境，助力企业发展 ]
 * +----------------------------------------------------------------------
 * | Copyright (c) 2018-2024 聊来All rights reserved.
 * +----------------------------------------------------------------------
 * | Licensed ( <a href="http://www.apache.org/licenses/LICENSE-2.0">apache</a> )
 * +----------------------------------------------------------------------
 * | @Author: 罗盼 <18970881148@qq.com>
 * +----------------------------------------------------------------------
 * | DateTime: 2025/2/28 14:55
 * +----------------------------------------------------------------------
 */
@Component
public class TcpServerHandler extends SimpleChannelInboundHandler<MsgInfoPojo.MsgInfo> {
    private final Logger logger = LoggerFactory.getLogger(TcpServerHandler.class);



    private MessageFactory messageFactory;
    @Autowired
    public void SetMessageChannel(MessageFactory messageFactory) {
        this.messageFactory = messageFactory;
    }

    /** 在初始化 netty 的时候,handler是new出来的,没有托管给spring容器管理,所以无法使用依赖注入(@Autowired)，因此项目在启动的时候执行该方法 */
    private static TcpServerHandler handler = null;
    @PostConstruct
    public void init() {
        if (handler == null) { handler = this; }
    }

    /**
     * 客户端与服务器第一次建立连接的时候触发
     * @param ctx ChannelHandlerContext
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) {
        logger.info("客户端建立TCP连接，通道开启：" + ctx.channel());

        Object data = handler.messageFactory.sendMessage(RequestType.CONNECTED, ctx.channel(),null);
        MsgInfoPojo.MsgInfo response = MsgInfoPojo.MsgInfo.newBuilder()
                .setRequestType(0)
                .setData(JSONUtil.toJsonStr(data))
                .build();
        ctx.channel().writeAndFlush(response);
    }


    /**
     * TODO 客户端与服务器断开连接的时候触发
     * @param ctx ChannelHandlerContext
     */
    @Override
    public void channelInactive(ChannelHandlerContext ctx) {
        logger.info("客户端断开TCP连接，通道关闭：" + ctx.channel());
    }

    /**
     * 接收、处理客户端发来的信息
     * @param ctx ChannelHandlerContext
     * @param msgInfo Object
     */
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, MsgInfoPojo.MsgInfo msgInfo) throws Exception {
        //logger.info("接收客户端发送的消息：" + msgInfo);

        RequestType type = RequestType.resolveEvent(msgInfo.getRequestType());
        Object data = handler.messageFactory.sendMessage(type, ctx.channel(), msgInfo.getData());
        if (ObjectUtil.isNotNull(data)) {
            assert type != null;
            MsgInfoPojo.MsgInfo response = MsgInfoPojo.MsgInfo.newBuilder()
                    .setRequestType(msgInfo.getRequestType())
                    .setData(JSONUtil.toJsonStr(data))
                    .build();
            ctx.channel().writeAndFlush(response);
        }
    }


//    @Override
//    public void channelRead(ChannelHandlerContext ctx, Object msg) {
//        MsgInfoPojo.MsgInfo msgInfo = (MsgInfoPojo.MsgInfo) msg;
//        //logger.info("接收客户端发送的消息：" + msgInfo);
//
//        RequestType type = RequestType.resolveEvent(msgInfo.getRequestType());
//        Object data = handler.messageFactory.sendMessage(type, ctx.channel(), msgInfo.getData());
//        if (ObjectUtil.isNotNull(data)) {
//            assert type != null;
//            MsgInfoPojo.MsgInfo response = MsgInfoPojo.MsgInfo.newBuilder()
//                    .setRequestType(msgInfo.getRequestType())
//                    .setData(JSONUtil.toJsonStr(data))
//                    .build();
//            ctx.channel().writeAndFlush(response);
//        }
//    }

    /**
     * 消息收、发完成
     * @param ctx ChannelHandlerContext
     */
    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) { ctx.flush(); }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        logger.error("消息异常：" + cause.getMessage());
        cause.printStackTrace();

        //if (ctx.channel().isActive()) { ctx.channel().close(); }
    }
}
